☆-とБ신ㅇl,행복ぁŀ기를,ばł라l요-☆

Swift 에서 객체간 통신 방법들

2020年05月07日

Delegate vs Notification vs KVO

왜 Swift 에는 이러한 세가지 패턴들이 있을까요?

바로 특정 이벤트가 발생했을 때 다른 객체(혹은 다수의 객체들)에게 알려주고 싶을 때 사용합니다.

즉 객체 간 소통이 필요할 때 사용합니다.

쉽게 예시를 들어봅시다.

로그인한 유저가 로그아웃을 하면 그에 따라 다른 화면에서 이벤트 발생을 받아 그에 따른 화면 처리를 할 때 사용할 수 있습니다.

Delegate

프로토콜을 정의하여 사용합니다.

프로토콜은 특정 작업이나 기능에 맞게 메서드, 속성과 같은 요구 사항들의 청사진(blueprint)를 정의하고 이러한 요구 사항들을 실제로 구현하기 위해서 class, struct, enum 에서 프로토콜을 따라 구현

장점

  • 재사용할 수 있는 코드를 작성할 수 있음
  • 객체와 객체간의 연결로 추적이 쉽다

단점

  • MVC 의 단점인 massive view controller 가 되기 쉽다. (코드가 많다)
  • delegate 사용을 위해서 구현해야하는 코드가 많다.
  • 다수의 객체들에게 이벤트를 호출하는 방식이 비효율적임
  • delegate 프로퍼티 선언 시 참조 순환을 막기 위해 weak으로 선언해야 함

Notification

NotificationCenter 을 사용하여 구독한 객체들에게 이벤트 발생을 알린다.

extension NSNotification.Name {
  static let genderChanged = Notification.Name("genderChanged")
}

NotificationCenter.default.addObserver(self, selector: #selector(reloadGender), name: .genderChanged, object: nil)

// post 되면 addObserver한 모든 객체의 이벤트가 발생
let notiCenter = NotificationCenter.default
notiCenter.post(name: .genderChanged, object: nil)

장점

  • 옵저버에 추가한 다수의 객체들에게 동시에 이벤트를 발생을 알릴 수 있음
  • 짧은 코드로 실행시킬 수 있음

단점

  • 이벤트가 발생했다는 것만 알 수 있고 별도의 값을 전달 받지는 않음
  • 많은 NotificationCenter 사용 시 코드의 흐름을 읽기 어려움

KVO

값의 변화를 감지할 때 사용한다. 예로들어 collectionView의 contentsize 의 값 변화를 감지할 때 사용한다. 이러한 애플 API 내의 변화를 감지할 때 사용한다.

private var observer: NSKeyValueObservation?

deinit {
    observer?.invalidate()
}

observer = collectionView.observe(\.contentSize, option: [.new]) { [weak self] (collect, size) in
      print(size)
    }
  }

Custom KVO 방식은 아래를 참조하여 작성하면 된다.

What is key-value observing?

정리

  • KVO: 한 객체가 다른 객체의 프로퍼티를 관찰하여 변경 사항을 찾을 수 있는 패턴
    • 프로퍼티의 상태에 반응하기 때문에 프로퍼티의 변화를 감지할 때 사용
  • Notification: 다수의 객체에게 동시에 이벤트 발생을 알릴 수 있다.
    • 다수의 객체가 이벤트 발생을 받고 뷰를 변경하는 경우에서 사용할 수 있다.
    • 1:다
  • Delegate: 재사용할 수 있는 프로토콜을 사용하고 프로토콜에 따른 코드를 작성함으로써 읽기 쉬운 코드를 작성할 수 있다.
    • 객체간 1:1





실제 프로젝트를 진행하다 보면 어느 부분에서 이 방식을 써야지 하고 생각하고 느끼게 됩니다.(가끔 이 판단이 틀릴 때도 있지만… 그때는 리팩토링..)

때에 따라 최적의 방식을 사용하면 될 것 같습니다.